﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Data.Common;

namespace ResourceBlender_Express {
    /// <summary>
    /// A window for managing format templates.
    /// </summary>
    public partial class WinTemplates : Window {
        private BackgroundWorker worker;

        /// <summary>
        /// Initializes a new <see cref="WinTemplates"/>.
        /// </summary>
        public WinTemplates() {
            InitializeComponent();
            lstTemplates.Items.SortDescriptions.Add(new System.ComponentModel.SortDescription("Name", System.ComponentModel.ListSortDirection.Ascending));
        }

        /// <summary>
        /// Loads the list of templates.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void Window_Loaded(object sender, RoutedEventArgs e) {
            LoadTemplates();
        }

        /// <summary>
        /// Refreshed the list of templates.
        /// </summary>
        private void LoadTemplates() {
            worker = new BackgroundWorker();
            worker.DoWork += (s, dwe) => {
                Database db = new Database();
                try {
                    db.OpenConnection();
                    using(Database.Command cmd = db.CreateCommand()) {
                        cmd.CommandText = string.Format("SELECT * FROM {0}templates", db.TablePrefix);
                        DbDataReader reader = cmd.ExecuteReader();
                        List<RBTemplate> templates = new List<RBTemplate>();
                        while(reader.Read()) {
                            templates.Add(new RBTemplate(int.Parse(reader["id"].ToString()), reader["name"].ToString(), reader["filename"].ToString(), reader["filestart"].ToString(), reader["fileend"].ToString(), reader["line"].ToString()));
                        }
                        dwe.Result = templates;
                    }
                } catch(Exception ex) {
                    dwe.Result = "Error connecting to the database: " + ex.Message;
                } finally {
                    if(db != null) {
                        try {
                            db.CloseConnection();
                        } catch { }
                    }
                }
            };
            worker.RunWorkerCompleted += (s, rwe) => {
                SetStatus(null, false);
                if(rwe.Result != null && rwe.Result is string) {
                    DialogBox.Show(this, rwe.Result.ToString(), "Database Error", DialogBox.DialogBoxType.OK, DialogBox.DialogBoxIcon.Error);
                } else {
                    DataContext = rwe.Result as List<RBTemplate>;
                }
            };
            SetStatus("Loading templates...", true);
            worker.RunWorkerAsync();
        }

        /// <summary>
        /// Shows a window to add a new template.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void AddTemplate(object sender, ExecutedRoutedEventArgs e) {
            WinAddTemplate dlg = new WinAddTemplate();
            dlg.Owner = this;
            if(dlg.ShowDialog() == true) {
                LoadTemplates();
            }
        }

        /// <summary>
        /// Determines whether the edit template command can be executed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.CanExecuteRoutedEventArgs"/> instance containing the event data.</param>
        private void CanExecuteEditTemplate(object sender, CanExecuteRoutedEventArgs e) {
            e.CanExecute = lstTemplates != null && lstTemplates.SelectedItem != null && (worker == null || !worker.IsBusy);
            e.Handled = true;
        }

        /// <summary>
        /// Shows a window to edit a template.
        /// </summary>
        private void EditTemplate(object sender, RoutedEventArgs e) {
            if(lstTemplates.SelectedValue == null)
                return;
            RBTemplate originalTemplate = lstTemplates.SelectedValue as RBTemplate;
            WinAddTemplate dlg = new WinAddTemplate(originalTemplate.Clone());
            dlg.Owner = this;
            if(dlg.ShowDialog() == true) {
                LoadTemplates();
            }
        }

        /// <summary>
        /// Determines whether the delete template command can be executed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.CanExecuteRoutedEventArgs"/> instance containing the event data.</param>
        private void CanExecuteDeleteTemplate(object sender, CanExecuteRoutedEventArgs e) {
            e.CanExecute = lstTemplates != null && lstTemplates.SelectedItem != null && (worker == null || !worker.IsBusy);
            e.Handled = true;
        }

        /// <summary>
        /// Deletes a template after the user has confirmed.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void DeleteTemplate(object sender, ExecutedRoutedEventArgs e) {
            if(lstTemplates.SelectedValue == null)
                return;
            RBTemplate template = lstTemplates.SelectedValue as RBTemplate;
            if(DialogBox.Show(this, string.Format("Are you sure you want to delete the template '{0}'?", template.Name), "Confirm Delete", DialogBox.DialogBoxType.YesNo, DialogBox.DialogBoxIcon.Question) == DialogBox.DialogBoxButton.Yes) {
                worker = new BackgroundWorker();
                worker.DoWork += (s, dwe) => {
                    Database db = new Database();
                    try {
                        db.OpenConnection();
                        using(Database.Command cmd = db.CreateCommand()) {
                            cmd.CommandText = "DELETE FROM " + db.TablePrefix + "templates WHERE id = @p";
                            cmd.AddParameterWithValue("@p", template.ID);
                            cmd.ExecuteNonQuery();
                        }
                    } catch(Exception ex) {
                        dwe.Result = "Error connecting to the database: " + ex.Message;
                    } finally {
                        if(db != null) {
                            try {
                                db.CloseConnection();
                            } catch { }
                        }
                    }
                };
                worker.RunWorkerCompleted += (s, rwe) => {
                    SetStatus(null, false);
                    if(rwe.Result != null) {
                        DialogBox.Show(this, rwe.Result.ToString(), "Database Error", DialogBox.DialogBoxType.OK, DialogBox.DialogBoxIcon.Error);
                    }
                    LoadTemplates();
                };
                SetStatus("Deleting template...", true);
                worker.RunWorkerAsync();
            }
        }

        /// <summary>
        /// Shows the help file.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.ExecutedRoutedEventArgs"/> instance containing the event data.</param>
        private void ShowHelp(object sender, ExecutedRoutedEventArgs e) {
            Utils.OpenHelp("Templates.html");
        }

        /// <summary>
        /// Closes the window.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.ExecutedRoutedEventArgs"/> instance containing the event data.</param>
        private void CloseWindow(object sender, ExecutedRoutedEventArgs e) {
            DialogResult = true;
            Close();
        }

        /// <summary>
        /// Sets the text on the status message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="showProgress"><c>true</c> if the progress bar should be shown, otherwise <c>false</c>.</param>
        private void SetStatus(string message, bool showProgress) {
            prgStatus.Visibility = showProgress ? Visibility.Visible : Visibility.Hidden;
            if(message == null) {
                lblStatus.Visibility = Visibility.Hidden;
            } else {
                lblStatus.Visibility = Visibility.Visible;
                lblStatus.Content = message;
            }
        }
    }
}
